 /*      STypes.h
 *
 *      Copyright 2009-2010 virpool <virpool@ukrpost.ua>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#ifndef __STYPES_H_
#define __STYPES_H_

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <list>
#include "SObject.h"

using namespace std;

/*
 * Return codes from methods
 */
typedef enum {
	S_YES,
	S_NO,
	S_ADD_VARIABLE_OK,
	S_ADD_METHOD_OK,
	S_VARIABLE_DUBLICATE,
	S_METHOS_DUBLICATE,
	S_INVOKE_OK,
	S_INVOKE_FALSE,
	S_INVOKE_INCORRECT, // if invoke method with incorrect arguments
	S_INVOKE_NOMETHOD
} S_RESULTS;

/*
 * Main operate types
 */
typedef enum {
	S_OBJECT,
	S_INT,
	S_FLOAT,
	S_BOOL,
	S_STRING,
	S_ARRAY,
	S_HASH,
 	S_FILE,
	S_TYPE,
 	S_VALUE
} S_ARG_TYPES;

class SObject;

typedef enum { NUM_NUM, NUM_INC, NUM_DEC } num_act;

typedef enum { e_eq, e_add, e_sub, e_mul, e_div, e_and, e_mod, e_or, e_xor } e_actions;

/*
 * Structure of method's parameter
 */
typedef struct
{
	void *val; // some value
	S_ARG_TYPES type; // and his type
} s_param;

/*
 * prototype of all usuable methods of objects
 */
typedef int (*s_func)(SObject*, s_param *res, list<s_param>*);

/*
 * record of some variable in registry
 */
typedef struct
{
	SObject *obj;
	int clinks; // count of links by object. if this == 0 then object may be delete by gc
} s_obj;

typedef struct
{
	S_ARG_TYPES type;
	string id;
} s_method_param;

typedef list<s_param> param_list;

typedef enum 
{
	s_new,
	s_delete,
	s_mov,
	s_put,
 	s_puts,
 	s_input,
    s_operation,
	s_expr,
 	s_if,
  	s_while,
    s_for,
	s_for_cont,
	s_break,
 	s_method,
  	s_this,
  	
  
  	s_add,
    s_sub,
	s_mul,
 	s_div,
  	s_mod,
   	s_and,
	s_or,
 	s_land,
  	s_lor,
   	s_xor,
	s_shr,
 	s_shl,
  	s_ge,
    s_le,
	s_eq,
 	s_ne,
  	s_g,
   	s_l,
	s_minus,
 	s_no,
  	// for obj += etc
  	s_sadd,
	s_ssub,
	s_smul,
	s_sdiv,
 	s_smod,
  	s_sand,
	s_sor,
 	s_sxor
} s_comm;

/*
 * record of command for virtual machine
 */
struct s_command
{
	s_command *parent;
	list<s_command*> child;
	list<s_command*> alt_child;
	
	list<s_comm> expr_stack;
	list<s_command*> if_expr_child;
	
	s_command *for_init;
	bool for_type;
	list<string> coll_id;

	s_comm comm;
	list<string> buf;
	list<string> tmpbuf;

	s_param **params;
	int count_params;
	
	bool is_value;
	int val_int;
	float val_float;
	string val_string;
	bool val_bool;
	string hash_key;
	
	bool value;
	bool breaking;
	list<s_method_param*> fparams;
	
	S_ARG_TYPES arg_type; // it's needed for: new (Type, value); 
	S_ARG_TYPES arg_type_arr; // for arrays
	S_ARG_TYPES is_array_type;
	
	param_list args;
	
	bool is_var;
	bool is_obj;
	string obj_id;
	bool is_oper_with_params_now;
	bool is_ok_array;
	bool is_expr_now;
	bool is_expr_error;
	string last_expr_error;
	bool is_array_operation;
	bool is_array;
	bool is_array_dyn;
	bool is_hash_operation;
	bool is_put_single_out;
	string out;
	bool is_id;
	
	S_ARG_TYPES expr_type;
	SObject *expr_obj_left;
	
	e_actions expr_act;
	
	num_act na;
	
	unsigned int op_param_cnt;
	
	bool is_string;
	bool is_params;
	
	unsigned int is_array_index;
	int array_indx;
	
	~s_command() { child.clear(); alt_child.clear(); buf.clear(); fparams.clear(); if_expr_child.clear(); };
};

typedef map<string, s_command*> s_methods;

#endif /* STYPES_H_ */
